package Modele;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;

//import com.sun.tools.javac.util.Pair;

import Modele.Matrice;
/**
 * Classe permettant de lire les fichiers contenant les poids et les biais des diff�rentes couches des r�seaux de neuronnes
 * Les fichiers sont sauvegard�s au format soit Weighti.txt soit Biasi.txt. Le i �tant � remplac� par le i de la ieme it�ration d'apprentissage.
 * @author philippestepniewski
 *
 */
public class Reader{

	/**
	 * Converti un fichier en un ArrayList contenant des matrices. Chaque matrice repr�sente l'�tat des param�tres d'une couche de neurones dont les information sont dans le fichier lu
	 * @param num_iteration le i de l'iteration
	 * @param type Quelle type de fichier veut on lire? "Weight" ou "Bias"
	 * @param liste_poids Le tableau pour stocker les matrices de la ieme iteration
	 */
	public static void convertWeightBiasToArray(int num_iteration,ArrayList<Matrice> liste_poids,double bias){
		try {
			String filePath = "WeightAndBias"+num_iteration+".txt";
			Scanner scanner;
			scanner = new Scanner(new File(filePath));
			//double ligne[];
			//int num_poids = -100;
			int nb_ligne;
			int nb_col;
			int infos[];
			infos=new int[4];
			while (scanner.hasNextLine()) {
				String line=scanner.nextLine();
				if(line.contains("Weight")){
					infos=read_infos(line,"Weight");
				}
				//num_poids = infos[1];
				nb_ligne = infos[2];
				nb_col = infos[3];
				Matrice mat=new Matrice(nb_ligne, nb_col);

				read_weight_biais(mat,bias, nb_ligne, nb_col, line, scanner);
				liste_poids.add(mat);
			}
			scanner.close();
		} catch (FileNotFoundException e) {
			System.out.println("fichier non trouv�");
			e.printStackTrace();
		}	
	}

        

	/**
	 *  m�thode qui lit une ligne avec des valeurs ( pas l'entete)	
	 *  Attention: cette fonction est une sous fonction utilis�e uniquement dans convertFichierToArray donc th�oriquement vous aurez jamais � l'utiliser vous m�me
	 * @param mat matrice de stockage des valeurs du bias ou du weight
	 * @param nb_ligne nombre de ligne du weight ou bias
	 * @param nb_col nombre de colonne du weight ou bias
	 * @param line ligne en cours de lecture
	 * @param scanner scanner lisant le fichier
	 */
	public  static void read_weight_biais(Matrice mat,double bias,int nb_ligne,int nb_col,String line,Scanner scanner){
		double nombre;
		for(int j=0;j<nb_ligne;j++){
			if(scanner.hasNextLine()){
				line=scanner.nextLine();
			}
			String tabval[]=new String[nb_col];
			tabval=line.split(" ");
			for(int i=0;i<nb_col;i++){
				if(i==0){
					nombre=Float.parseFloat(tabval[i]);
					bias=nombre;
				}
				else{
					nombre=Float.parseFloat(tabval[i]);
					mat.insertAtIJ(j,i,nombre);
				}
			}

		}
	}
	/**
	 * M�thode qui lit les infos d'un weight ou d'un bias dans un fichier. L'entete en fait. Elle recupere le numero du weight ou bias, le nombre de ligne et de colonne
	 * @param ligne ligne en cours de lecture
	 * @param type Bias ou Weight ou Activation
	 * @return un tableau avec les infos
	 */
	public static int[] read_infos(String ligne,String type){
		int tab[];
		String tabval[];
		if(type.equals("Activation")|| type.equals("Kmeans")){
			tabval=new String[3];
			tab=new int[3];
		}
		else{
			tabval=new String[4];
			tab=new int[4];
		}

		tabval=ligne.split(" ");
		for(int i=0;i<tabval.length;i++){
			if(!tabval[i].equals("Weight") && !tabval[i].equals("Bias")&& !tabval[i].equals("Activation") && !tabval[i].equals("Kmeans")){
				tab[i]=Integer.parseInt(tabval[i]);
			}
		}		
		return tab;
	}
	/**
	 * Fonction qui lit un fichier contenant les activations de tous les neuronnes du NN a une iteration i
	 * Le fichier est obligatoirement appel� "activationI.txt"
	 * @param num_iteration l'iteration en question
	 * @param nbCouches nbre de couches dans le r�seau. Entr�e comprise
	 * @return
	 */
	
	public static ArrayList<double[]> read_activation(String string){
		String tabval[];
		//String filePath = "a"+string+"_"+exemplei+".txt";
		ArrayList<double[]> toutecouches = new ArrayList<double[]>();
		Scanner scanner;
		int infos[];
		double activN[];
		double nombre;
		int nbcol=0;
		activN = new double[nbcol];
		try {
			scanner = new Scanner(new File(string));
			while (scanner.hasNextLine()) {
				String line=scanner.nextLine();
				if(line.contains("Activation")){
					infos=new int[3];
					infos=read_infos(line,"Activation");
					nbcol=infos[2];
					activN=new double[nbcol];
					line=scanner.nextLine();
				}
				tabval=line.split(" ");
				for(int i=0;i<nbcol;i++){
					nombre=Double.parseDouble(tabval[i]);
					activN[i]=nombre;
				}
				toutecouches.add(activN);
			}

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return toutecouches;

	}
        /**
         * Lit dans un fichier texte les données concernant les représentants des clusters kmeans
         * @param string
         * @return la liste des représentants des clusters kmeans , pour chaque couche
         */
        public static ArrayList<double[]> read_kmeans(String string){
		ArrayList<double[]> toutkmeans = new ArrayList<double[]>();
                String tabval[];
		Scanner scanner;
		int infos[];
		double[] activN ;
		double nombre;
		int nbcol=0;

		try {
			scanner = new Scanner(new File(string));
			while (scanner.hasNextLine()) {
				String line=scanner.nextLine();
				if(line.contains("Kmeans")){
					infos=new int[3];
					infos=read_infos(line,"Kmeans");
					nbcol=infos[2];

					line=scanner.nextLine();
				}
                                activN = new double[nbcol];
				tabval=line.split(" ");
				for(int i=0;i<nbcol;i++){
					nombre=Double.parseDouble(tabval[i]);
					activN[i]=nombre;
				}
                                toutkmeans.add(activN);

			}

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

                return toutkmeans;
	}

	/**
	 * Fonction qui lit un fichier contenant TOUT les r�sultats de l'execution d'un NN
	 * @param nb_donnee nombre de donn�es pass�e dans le NN
	 * @return un tableau d'entier contenant l'�tiquette a chaque fois
	 */
	public static ArrayList<Pair<Integer,Integer>> readClassif(String name){
		String tabval[];
		String filePath = "Classif_"+name+".txt";
		ArrayList<Pair<Integer,Integer>> classif = new ArrayList<Pair<Integer,Integer>>();
		Scanner scanner;
		try {
			scanner = new Scanner(new File(filePath));
                        String line=scanner.nextLine();
			while (scanner.hasNextLine()) {
				line=scanner.nextLine();
				tabval=line.split(" ");
				Pair<Integer,Integer> temp = new Pair<Integer,Integer>(Integer.parseInt(tabval[0]),Integer.parseInt(tabval[1]));
				classif.add(temp);
			}	
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return classif;	
	}

        /**
	 * Fonction qui lit un fichier contenant l'erreur
	 * @param nb_donnee nombre de donn�es pass�e dans le NN
	 * @return un tableau d'entier contenant l'�tiquette a chaque fois
	 */
	public static ArrayList<Pair<Integer,Double>> readCurric(String name){
		String tabval[];
                String tabpuisance[];
		String filePath = name;
                double puissance;
		ArrayList<Pair<Integer,Double>> classif = new ArrayList<Pair<Integer,Double>>();
		Scanner scanner;
		try {
			scanner = new Scanner(new File(filePath));
                        String line=scanner.nextLine();
			while (scanner.hasNextLine()) {
				line=scanner.nextLine();
				tabval=line.split(" ");
                                if(tabval[1].contains("e")){
                                    tabpuisance=tabval[1].split("e");
                                    puissance=Double.parseDouble(tabpuisance[0])*(Math.pow(10.0,Double.parseDouble(tabpuisance[1])));
                                }
                                else{
                                    puissance=Double.parseDouble(tabval[1]);
                                }
				Pair<Integer,Double> temp = new Pair<Integer,Double>(Integer.parseInt(tabval[0]),puissance);
				classif.add(temp);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return classif;
	}


        /**
         * Lit l'erreur quadratique dans le fichier la contenant
         * @param name
         * @return la liste des erreurs quadratique au cours des itération
         */
        public static ArrayList<Double> readErreur(String name){
		String tabval[];
		String filePath = "ErreurQuadra"+name+".txt";
		ArrayList<Double> classif = new ArrayList<Double>();
		Scanner scanner;
		try {
			scanner = new Scanner(new File(filePath));

			while (scanner.hasNextLine()) {
				String line=scanner.nextLine();
				tabval=line.split(" ");
				classif.add(Double.parseDouble(tabval[0]));
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return classif;
	}

        /**
         * lit l'appartenance des neurones d'une couche au cluster de kmeans pour une couche
         * @param nbCouches
         * @return l'appartenance des neurones d'une couche au cluster de kmeans pour une couche
         */
        public static ArrayList<Integer> readCluster(int nbCouches){

                ArrayList<Integer> tabval=new ArrayList<Integer>();

		String filePath = "Ykmean"+(nbCouches);
		Scanner scanner;
		try {
			scanner = new Scanner(new File(filePath));

			while (scanner.hasNextLine()) {
				String line=scanner.nextLine();
                                    tabval.add(Integer.parseInt(line));
                                
                        }
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return tabval;
        }
    /**
     * Lit le taux de réussite de l'expérience dans le fichier classif (première ligne uniquement)
     * @param nomExp
     * @return le taux de réussite de l'expérience
     */
    static double readTaux(String nomExp) {
                double taux=0;
		String filePath = "Classif_"+nomExp+".txt";
		Scanner scanner;
		try {
			scanner = new Scanner(new File(filePath));
                        String line=scanner.nextLine();
                        taux=Double.parseDouble(line);
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return taux;
    }




}

